# Contributor: Oleg A. Khlybov <fougas@mail.ru>

# This package provides multiple library build flavors differentiated by
# the 3-character suffix XYZ as follows:
#
#  * X is the scalar type based on the Netlib's SDCZ notation:
#    - A for multiprecision or precision-neutral build
#    - S for single precision real
#    - D for double precision real
#    - C for single precision complex
#    - Z for double precision complex
#
#  * Y is the execution model:
#    - S for sequential code
#    - M for MPI parallel code
#    - T for multithreaded code, either bare threading or OpenMP, OpenACC etc.
#    - H for heterogeneous code with CUDA, OpenCL etc.
#
#  * Z is the build type:
#    - O for optimized build
#    - G for debugging build
#
# The suffix is used in the static and dynamic libraires as well as in PkgConfig .pc files.
# That is the ZMO suffix designates the optimized MPI parallel double precision complex library flavor.
# Consider the `pkg-config slepc-zmo --cflags` command to obtain the build-specific compilation flags.

_realname=slepc
pkgbase=mingw-w64-${_realname}
pkgname=("${MINGW_PACKAGE_PREFIX}-${_realname}")
pkgver=3.18.2
petsc_pkgver=3.18.3
pkgrel=1
arch=('any')
mingw_arch=('mingw32' 'mingw64' 'ucrt64' 'clang64' 'clang32')
pkgdesc="Scalable library for eigenvalue problem computations (mingw-w64)"
depends=("${MINGW_PACKAGE_PREFIX}-petsc>=${petsc_pkgver}")
makedepends=("python"
             "${MINGW_PACKAGE_PREFIX}-cc"
             $([[ ${MINGW_PACKAGE_PREFIX} == *-clang-* ]] || echo "${MINGW_PACKAGE_PREFIX}-fc")
             "${MINGW_PACKAGE_PREFIX}-petsc-build>=${petsc_pkgver}")
optdepends=("${MINGW_PACKAGE_PREFIX}-tcl: build & run test suite")
options=('strip' 'staticlibs')
license=('spdx:BSD-2-Clause')
url="https://slepc.upv.es/"
source=("https://slepc.upv.es/download/distrib/${_realname}-${pkgver}.tar.gz"
        'all.tcl'
        'tclbuildtest.tcl'
        'slepc.test')
noextract=("${_realname}-${pkgver}.tar.gz")
sha256sums=('5bd90a755934e702ab1fdb3320b9fe75ab5fc28c93d364248ea86a372fbe6a62'
            'ec5072630e1c0309fe383669e9187790cd135a393c67bc4bc35cf60b0ba396ff'
            '15c7af25b91406d5fe5f26cfe00963b6cfde1c3dd466eb25f1b6fae299934966'
            '47237bd53f15e9d204b7c871ef887d9b6d11e0add1409a6eeb1a122f4b302265')

prepare() {
  mkdir -p $srcdir/build-${MSYSTEM} && cd $srcdir/build-${MSYSTEM}
  tar xzf $srcdir/${_realname}-${pkgver}.tar.gz
}

build() {
  . ${MINGW_PREFIX}/src/petsc-*/petsc
  cd  "${srcdir}/build-${MSYSTEM}/${_realname}-${pkgver}"
  for build in ${petsc_builds}; do
    export SLEPC_DIR=`pwd`
    export PETSC_ARCH=${build}
    export PETSC_DIR=${MINGW_PREFIX}/src/petsc-${petsc_pkgver}
    /usr/bin/python configure 
    make
    (
      cd ${build}/lib
      case ${build} in
        *o) strip -S *.a ;;
      esac
      ${CC} -shared -Wl,--enable-auto-import -Wl,--export-all-symbols \
        -o lib${_realname}-${build}.dll -Wl,--out-implib,lib${_realname}.dll.a \
        -Wl,--whole-archive lib${_realname}.a -Wl,--no-whole-archive \
        $(pkg-config msmpi petsc-${build} --libs) $(pkg-config openblas --libs)
    )
  done
}

package() {
  cd ${srcdir}/build-${MSYSTEM}/${_realname}-${pkgver}
  mkdir -p ${pkgdir}${MINGW_PREFIX}/{bin,lib/pkgconfig,lib/${_realname},include/${_realname},share/test/${_realname}}
  (
    cd include
    cp *.h ${pkgdir}${MINGW_PREFIX}/include/${_realname}
    cd ${_realname}
    cp -R finclude ${pkgdir}${MINGW_PREFIX}/include/${_realname}
    cd ${pkgdir}${MINGW_PREFIX}/include/${_realname}
    find . \( ! -name '*.h' -a -type f \) -delete
  )
  (
    cd ${srcdir}
    cp {all,tclbuildtest}.tcl slepc.test ${pkgdir}${MINGW_PREFIX}/share/test/${_realname}
  )
  (
    cd src/eps/tutorials
    cp ex1.c ex1f.F ${pkgdir}${MINGW_PREFIX}/share/test/${_realname}
  )
  for build in ${petsc_builds}; do
    (
      cd ${build}/lib
      mkdir -p ${pkgdir}${MINGW_PREFIX}/lib/${_realname}/${build}
      cp *.a ${pkgdir}${MINGW_PREFIX}/lib/${_realname}/${build}
      cp *.dll ${pkgdir}${MINGW_PREFIX}/bin
    )
    (
      cd ${build}/include
      mkdir -p ${pkgdir}${MINGW_PREFIX}/include/${_realname}/${build}
      cp *.h ${pkgdir}${MINGW_PREFIX}/include/${_realname}/${build}
      if [[ ${MINGW_PACKAGE_PREFIX} != *-clang-* ]]; then
        cp *.mod ${pkgdir}${MINGW_PREFIX}/include/${_realname}/${build}
      fi
    )
    case ${build} in
      ?m?) desc="MPI parallel";;
      ?t?) desc="OpenMP multithreaded";;
      ?s?) desc="Sequential";;
    esac
    case ${build} in
      z*|d*) desc="$desc double precision";;
      c*|s*) desc="$desc single precision";;
    esac
    case ${build} in
      z*|c*) desc="$desc complex";;
    esac
    echo "
      prefix=${MINGW_PREFIX}
      libdir=\${prefix}/lib/${_realname}
      includedir=\${prefix}/include/${_realname}
      Name: ${_realname}
      URL: ${url}
      Version: ${pkgver}
      Description: ${desc} SLEPc build
      Requires: petsc-${build}
      Cflags: -I\${includedir}/${build} -I\${includedir}
      Libs: -L\${libdir}/${build} -l${_realname}
    " | sed '/^\s*$/d;s/^\s*//' > ${pkgdir}${MINGW_PREFIX}/lib/pkgconfig/${_realname}-${build}.pc
  done
}
